home *** CD-ROM | disk | FTP | other *** search
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- #import "RIBNuPatch.h"
-
- @implementation RIBNuPatch
-
- + initialize { return [RIBNuPatch setVersion:1], self; }
-
- - (BOOL)hasBoundingBox { return YES; }
-
- - init
- {
- [super init];
-
- nU = nV = uOrder = vOrder = 0;
- uKnot = vKnot = NULL;
- uMin = uMax = vMin = vMax = 0.0;
- nVPlusVOrder = (char *)NXZoneMalloc([self zone], 128);
- nUPlusUOrder = (char *)NXZoneMalloc([self zone], 128);
- tesselationVector[0] = 6.0;
- tesselationVector[1] = 6.0;
-
- return self;
- }
-
- - awake
- {
- [super awake];
-
- return self;
- }
-
- - free
- {
- //if (uKnot) { free(uKnot); }
- //if (vKnot) { free(vKnot); }
- //free(nVPlusVOrder);
- //free(nUPlusUOrder);
-
- return [super free];
- }
-
- - copyFromZone:(NXZone *)zone
- {
- id newCopy = [super copyFromZone:zone];
-
- NXLogError("WARNING: copyFromZone: incompletely implemented for %s : I'm leaking memory in -free",
- [[self class] name]);
- return newCopy;
- }
-
- - setNU:(RtInt)newNU uOrder:(RtInt)newUOrder uKnot:(RtFloat *)newUKnot uMin:(RtFloat)newUMin uMax:(RtFloat)newUMax
- nV:(RtInt)newNV vOrder:(RtInt)newVOrder vKnot:(RtFloat *)newVKnot vMin:(RtFloat)newVMin vMax:(RtFloat)newVMax
- n:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector
- printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
- {
- nU = newNU;
- nV = newNV;
- uOrder = newUOrder;
- vOrder = newVOrder;
- uKnot = newUKnot;
- vKnot = newVKnot;
- uMin = newUMin;
- uMax = newUMax;
- vMin = newVMin;
- vMax = newVMax;
-
- //
- if (uOrder > 4)
- { tesselationVector[0] = 1.0;
- }
- if (uOrder == 4)
- { tesselationVector[0] = 2.0;
- }
- if (uOrder == 3)
- { tesselationVector[0] = 4.0;
- }
- if (uOrder == 2)
- { tesselationVector[0] = 6.0;
- }
-
- //
- if (vOrder > 4)
- { tesselationVector[1] = 1.0;
- }
- if (vOrder == 4)
- { tesselationVector[1] = 2.0;
- }
- if (vOrder == 3)
- { tesselationVector[1] = 4.0;
- }
- if (vOrder == 2)
- { tesselationVector[1] = 6.0;
- }
-
-
- [self setN:newN tokens:newTokens parms:newParms archiveVector:newArchiveVector printfTypeVector:newPrintfTypeVector printfNVector:newPrintfNVector];
-
- dirtyBoundingBox = TRUE;
- return self;
- }
-
- - (RtInt)nU { return nU; }
- - (RtInt)uOrder { return uOrder; }
- - (RtFloat *)uKnot { return uKnot; }
- - (RtFloat)uMin { return uMin; }
- - (RtFloat)uMax { return uMax; }
- - (RtInt)nV { return nV; }
- - (RtInt)vOrder { return vOrder; }
- - (RtFloat *)vKnot { return vKnot; }
- - (RtFloat)vMin { return vMin; }
- - (RtFloat)vMax { return vMax; }
-
-
- - (BOOL)theSameAs:otherRIBCommand
- {
- int i;
- RtFloat *otherUKnot, *otherVKnot;
-
-
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
- if (nU != [otherRIBCommand nU])
- { return NO;
- }
- if (nV != [otherRIBCommand nV])
- { return NO;
- }
- if (uOrder != [otherRIBCommand uOrder])
- { return NO;
- }
- if (vOrder != [otherRIBCommand vOrder])
- { return NO;
- }
- if (uMin != [otherRIBCommand uMin])
- { return NO;
- }
- if (uMax != [otherRIBCommand uMax])
- { return NO;
- }
- if (vMin != [otherRIBCommand vMin])
- { return NO;
- }
- if (vMax != [otherRIBCommand vMax])
- { return NO;
- }
-
- otherUKnot = [otherRIBCommand uKnot];
- for (i = 0; i < (nU + uOrder); i++)
- { if (uKnot[i] != otherUKnot[i])
- { return NO;
- }
- }
-
- otherVKnot = [otherRIBCommand vKnot];
- for (i = 0; i < (nV + vOrder); i++)
- { if (vKnot[i] != otherVKnot[i])
- { return NO;
- }
- }
-
- return [super theSameAs:otherRIBCommand];
- }
-
-
- - (BOOL)similarTo:otherRIBCommand
- {
- int i;
- RtFloat *otherUKnot, *otherVKnot;
-
-
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
- if (nU != [otherRIBCommand nU])
- { return NO;
- }
- if (nV != [otherRIBCommand nV])
- { return NO;
- }
- if (uOrder != [otherRIBCommand uOrder])
- { return NO;
- }
- if (vOrder != [otherRIBCommand vOrder])
- { return NO;
- }
- if (uMin != [otherRIBCommand uMin])
- { return NO;
- }
- if (uMax != [otherRIBCommand uMax])
- { return NO;
- }
- if (vMin != [otherRIBCommand vMin])
- { return NO;
- }
- if (vMax != [otherRIBCommand vMax])
- { return NO;
- }
-
- otherUKnot = [otherRIBCommand uKnot];
- for (i = 0; i < (nU + uOrder); i++)
- { if (uKnot[i] != otherUKnot[i])
- { return NO;
- }
- }
-
- otherVKnot = [otherRIBCommand vKnot];
- for (i = 0; i < (nV + vOrder); i++)
- { if (vKnot[i] != otherVKnot[i])
- { return NO;
- }
- }
- return YES;
- }
-
-
- - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- // due to a bug in QuickRenderMan, the default tesselation values are way too high vis.a.vis. NURBS
- // Therefore, I wrap a call to RiGeometricApproximation here to speed things up...
- RiAttributeBegin();
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
- RiNuPatchV(nU, uOrder, uKnot, uMin, uMax, nV, vOrder, vKnot, vMin, vMax, n, tokens, parms);
- RiAttributeEnd();
- return self;
- }
-
- - (BOOL)isMotionBlurrable { return YES; }
-
- - writeEve:(NXStream *)stream atTabLevel:(int)tab
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "NuPatch %d %d {", nU, uOrder);
- for (i = 0; i < (nU + uOrder); i++)
- { NXPrintf(stream, "%f ", *(uKnot + i));
- }
- NXPrintf(stream, "} %f %f ", uMin, uMax);
- NXPrintf(stream, "%d %d {", nV, vOrder);
- for (i = 0; i < (nV + vOrder); i++)
- { NXPrintf(stream, "%f ", *(vKnot + i));
- }
- NXPrintf(stream, "} %f %f ", vMin, vMax);
-
- [super writeParameterList:stream];
- return self;
- }
-
- - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
- {
- int i, k;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "Separator {\n");
-
- // need to print out my points and other stuff here...
- [self writeParameterListForInventor:stream atTabLevel:(tab+1)];
-
- // if ((uMin || vMin) != 0.0) || ((uMax || vMax) != 1.0), I need to dump out st values here...
-
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "NurbsSurface {\n");
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "numUControlPoints %d\n", nU);
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "numVControlPoints %d\n", nV);
-
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "uKnotVector [");
- for (i=0; i<(nU+uOrder-1); i++)
- { NXPrintf(stream, "%f, ", uKnot[i]);
- }
- NXPrintf(stream, "%f]\n", uKnot[i]);
-
- for (k = 0; k < (tab+2); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "vKnotVector [");
- for (i=0; i<(nV+vOrder-1); i++)
- { NXPrintf(stream, "%f, ", vKnot[i]);
- }
- NXPrintf(stream, "%f]\n", vKnot[i]);
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n");
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n");
-
- return self;
- }
-
-
- #define typeVector "iiiiffff"
- #define typeValues &nU, &nV, &uOrder, &vOrder, &uMin, &uMax, &vMin, &vMax
-
- - read:(NXTypedStream*)stream
- {
- int version;
-
-
- [super read:stream];
-
- nVPlusVOrder = (char *)malloc(128);
- nUPlusUOrder = (char *)malloc(128);
-
- NX_DURING
- version = NXTypedStreamClassVersion(stream,"RIBNuPatch");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1) {
- NXReadTypes(stream, typeVector, typeValues);
- uKnot = (RtFloat *)NXZoneMalloc([self zone], (int)(nU + uOrder)*sizeof(int));
- vKnot = (RtFloat *)NXZoneMalloc([self zone], (int)(nV + vOrder)*sizeof(int));
- NXReadArray(stream, "f", (int)(nU + uOrder), uKnot);
- NXReadArray(stream, "f", (int)(nV + vOrder), vKnot);
- NXReadArray(stream, "f", 2, tesselationVector);
- }
- NX_HANDLER
- NXLogError("in read: %s, exception [%d] raised.\n",
- [[self class] name], NXLocalHandler.code);
- return nil;
- NX_ENDHANDLER
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
- NXWriteTypes(stream, typeVector, typeValues);
- NXWriteArray(stream, "f", (int)(nU + uOrder), uKnot);
- NXWriteArray(stream, "f", (int)(nV + vOrder), vKnot);
- NXWriteArray(stream, "f", 2, tesselationVector);
- return self;
- }
-
- @end
-